package com.ms.orm.conditions.segments;

import com.ms.orm.conditions.ISqlSegment;
import com.ms.orm.enums.SqlKeyword;

import java.util.List;
import java.util.stream.Collectors;
/**
* 普通片段:
* @author miemie
* @since 2018-06-27
*/
@SuppressWarnings("serial")
public class NormalSegmentList extends AbstractISegmentList {

    /**
     * 是否处理了的上个 not
     */
    private boolean executeNot = true;

    NormalSegmentList() {
        this.flushLastValue = true;
    }

    /**
     * 把新的 sql片段集合 添加到当前集合中
     * @param list         传入进来的 ISqlSegment 集合
     * @param firstSegment ISqlSegment 传入进来的里的 集合里第一个值
     * @param lastSegment  ISqlSegment 传入进来的里的 集合里最后一个值
     * @return
     */
    @Override
    protected boolean transformList(List<ISqlSegment> list, ISqlSegment firstSegment, ISqlSegment lastSegment) {
        if (list.size() == 1) {
            /* 只有 and() 以及 or() 以及 not() 会进入 */
            if (!MatchSegment.NOT.match(firstSegment)) {
                //不是 not,且 当前 列表对象没有sql片段，直接返回，即where开始不能直接跟随 and 或者 or
                if (isEmpty()) {
                    //sqlSegment是 and 或者 or 并且在第一位,不继续执行
                    return false;
                }
                //判断片段集合最后一个值是否是  AND
                boolean matchLastAnd = MatchSegment.AND.match(lastValue);
                //判断片段集合最后一个值是否是  OR
                boolean matchLastOr = MatchSegment.OR.match(lastValue);
                //AND 或者 OR
                if (matchLastAnd || matchLastOr) {
                    //上次最后一个值是 and 或者 or
                    if (matchLastAnd && MatchSegment.AND.match(firstSegment)) {
                        //上次最后一个值是 and, 这里第一个也是and,返回false,不再进行处理
                        return false;
                    } else if (matchLastOr && MatchSegment.OR.match(firstSegment)) {
                        //上次最后一个值是 or, 这里第一个也是or,返回false,不再进行处理
                        return false;
                    } else {
                        //和上次的不一样，传进来的第一个值是 AND 或者 OR，和原始集合最后一个值不一样
                        //删除原始集合最后一个值，并更换原始集合最后一个值，
                        removeAndFlushLast();
                    }
                }
            } else {
                //当前传入集合第一个值是 NOT,设置 上一个not 状态为未处理，下一次添加需要进行判断处理？
                executeNot = false;
                return false;
            }
        } else {
            //传入集合原始大于1
            if (MatchSegment.APPLY.match(firstSegment)) {
                //如果第一个是值是APPLY，则删除
                list.remove(0);
            }
            if (!MatchSegment.AND_OR.match(lastValue) && !isEmpty()) {
                //如果第一个值 和 最后一个值不一样 同时原始集合非空，则添加 AND到原始集合，为了链接后续到 新集合元素
                add(SqlKeyword.AND);
            }
            if (!executeNot) {
                //上一次 遇到一个 not 还没处理，需要处理，在当前传入列表加入 首位加入NOT
                list.add(0, SqlKeyword.NOT);
                executeNot = true;
            }
        }
        return true;
    }

    /**
     * 把该集合中的sql片段，合并生成以 空格分隔的更大的 sql语句片段，
     * @return
     */
    @Override
    protected String childrenSqlSegment() {
        if (MatchSegment.AND_OR.match(lastValue)) {
            removeAndFlushLast();
        }
        final String str = this.stream().map(ISqlSegment::getSqlSegment).collect(Collectors.joining(SPACE));
        //左右加上括号
        return (LEFT_BRACKET + str + RIGHT_BRACKET);
    }

    /**
     * 清除集合
     *  1）设置 flushLastValue = true,表示下次处理（下次添加其他片段集合），先刷新最后一个值
     *  2）设置 executeNot = true,表示下次处理（下次添加其他片段集合），不用先进行 executeNot处理
     */
    @Override
    public void clear() {
        super.clear();
        flushLastValue = true;
        executeNot = true;
    }
}